package sort;

/**
 * 冒泡
 */
public class BubbleSort {

    /**
     * 1．比较相邻的前后二个数据，如果前面数据大于后面的数据，就将二个数据交换。<br>
     * <p>
     * 2．这样对数组的第0个数据到N-1个数据进行一次遍历后，最大的一个数据就“沉”到数组第N-1个位置。<br>
     * <p>
     * 3．N=N-1，如果N不为0就重复前面二步，否则排序完成。
     **/
    public static void bubbleSort1(int a[], int n) {
        int i, j;
        for (i = 0; i < n; i++) {
            for (j = 1; j < n - i; j++) {
                if (a[j - 1] > a[j])
                    swap(a, j - 1, j);
            }
        }
    }

    /**
     * 设置一个标志，如果这一趟发生了交换，则为true，否则为false。明显如果有一趟没有发生交换，说明排序已经完成。
     */
    public static void bubbleSort2(int a[], int n) {
        int j, k;
        boolean flag;
        k = n;
        flag = true;
        while (flag) {
            flag = false;
            for (j = 1; j < k; j++) {
                if (a[j - 1] > a[j]) {
                    swap(a, j - 1, j);
                    flag = true;
                }
            }
            k--;
        }
    }

    /**
     * 如果有100个数的数组，仅前面10个无序，后面90个都已排好序且都大于前面10个数字
     * ，那么在第一趟遍历后，最后发生交换的位置必定小于10，且这个位置之后的数据必定已经有序了
     * ，记录下这位置，第二次只要从数组头部遍历到这个位置就可以了。
     */
    public static void bubbleSort3(int a[], int n) {
        int start/*start*/, end/*end*/;
        int flag = n;//init flag
        while (flag > 0) {
            end = flag;
            flag = 0;//reset 0

            for (start = 1; start < end; start++) {
                if (a[start - 1] > a[start]) {
                    swap(a, start - 1, start);
                    flag = start;
                }
            }
        }
    }

    private static void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
}
